/**
 *
 */
package com.zed.api.common.collection;

import java.io.Serializable;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 使用list管理成员集合
 * <p>
 * 只读集合，线程安全
 * @author Zed
 *
 */
public abstract class MemberGroup<E> implements MemberCollection<E>, Serializable {

    /**
     *
     */
    private static final long serialVersionUID = -394583854771296436L;

    private List<E> items;

    /**
     * 无参构造方法，用于反序列化
     */
    protected MemberGroup() {
    }

    /**
     * 使用{@code items}创建新实例
     * @param items {@link List}
     */
    public MemberGroup(List<E> items) {
        this.items = this.transform(items);
    }

    /**
     * 是否包含{@code member}成员
     * @param member {@link E}
     * @return {@link boolean},返回{@code true}表达是，否则返回{@code false}
     */
    public boolean containsMember(E member) {
        return this.getMembers().contains(member);
    }

    @Override
    public E findByFilter(Predicate<E> filter) {
        return this.getMembers().stream().filter(filter).findAny().orElse(null);
    }

    @Override
    public List<E> getItems() {
        return this.getMembers();
    }

    @Override
    public List<E> getItemsByFilter(Predicate<E> filter) {
        return this.getMembers().stream()
                .filter(filter)
                .collect(Collectors.toList());
    }

    @Override
    public List<E> getItemsByAction(Function<Stream<E>, Stream<E>> action) {
        return action.apply(this.getMembers().stream())
                .collect(Collectors.toList());
    }

    @Override
    public int size() {
        return this.getMembers().size();
    }

    /**
     * 所有成员
     * @return {@link List}
     */
    protected List<E> getMembers() {
        return this.items;
    }

    /**
     * 构造方法调用的转换
     * @param items {@link List},构造方法入口的参数
     * @return {@link List}
     */
    protected List<E> transform(List<E> items) {
        return items == null ?
                Collections.emptyList() :
                Collections.unmodifiableList(items);
    }

    /**
     * 循环执行{@code action}
     * @param action {@link Consumer}
     */
    protected void foreach(Consumer<E> action) {
        this.items.forEach(action);
    }
}
